package com.forestar.mapControl.utils.mapConvert.geometry;

import com.forestar.mapControl.utils.mapConvert.geometry.coordinatesystem.CoordinateSystem;
import com.forestar.mapControl.utils.mapConvert.geometry.coordinatesystem.ZoneType;
import com.forestar.mapControl.utils.mapConvert.geometry.utils.GeometryUtils;
import com.mapzone.api.geometry.mzPath;
import com.mapzone.api.geometry.mzPoint;

import java.util.List;


public class GeoLine implements IGeometry
  {
    private CoordinateSystem coordSystem;
    private mzPath internalmzPath;
    private GeoPoint pointReUse;

    public GeoLine(CoordinateSystem coordSystem)
      {
        this.coordSystem = coordSystem;
        this.internalmzPath = new mzPath();
        int nSrid = coordSystem.getSrid();
        this.internalmzPath.setSrid(nSrid);
        pointReUse = new GeoPoint(coordSystem, 0.0, 0.0);
      }

    // TODO 此处不定是Path对象，path不是顶级对象 liubo 2016年7月17日16:26:01
    public GeoLine(CoordinateSystem coordSystem, mzPath path)
      {
        this.coordSystem = coordSystem;
        this.internalmzPath = path;
        int nSrid = coordSystem.getSrid();
        this.internalmzPath.setSrid(nSrid);
        pointReUse = new GeoPoint(coordSystem, 0.0, 0.0);
        // buildMemory();
      }

    @Override
    public GeometryType getGeometryType()
      {
        return GeometryType.GeometryTypePolyline;
      }

    public double getPointX(int nIndex)
      {
        return internalmzPath.GetPoint(nIndex).getX();
      }

    public double getPointY(int nIndex)
      {
        return internalmzPath.GetPoint(nIndex).getY();
      }

    public int getPointCount()
      {
        return internalmzPath.getPointCount();
      }

    @Override
    public CoordinateSystem getCoordinateSystem()
      {
        return coordSystem;
      }

    @Override
    public Envelope getEnvelope()
      {
        return GeometryUtils.getEnvelope(internalmzPath);
      }

    public boolean addPoints(List<GeoPoint> geoPoints)
      {
        for (int i = 0; i < geoPoints.size(); i++)
          {
            GeoPoint point = geoPoints.get(i);
            CoordinateSystem.projectPoint(point, pointReUse);
            double dx = pointReUse.getX();
            double dy = pointReUse.getY();
            internalmzPath.AddPoint(dx, dy);
          }
        return true;
      }

    public boolean addPoint(GeoPoint point)
      {
        CoordinateSystem.projectPoint(point, pointReUse);
        double dx = pointReUse.getX();
        double dy = pointReUse.getY();
        internalmzPath.AddPoint(dx, dy);
        return true;
      }

    public void removeAll()
      {
        int nPointCount = internalmzPath.getPointCount();
        while (nPointCount > 0)
          {
            internalmzPath.RemovePoint(0);
            nPointCount = internalmzPath.getPointCount();
          }
      }

    @Override
    public void setCoordinateSystem(CoordinateSystem coordSystem)
      {
        this.coordSystem = coordSystem;
      }

    public boolean replaceAllPoints(int pointsCount, double[] xy)
      {
        return this.internalmzPath.replaceAllPoints(pointsCount, xy);
      }

    public double[] getPoints()
      {
        return internalmzPath.GetPoints();
      }

    @Override
    public IGeometry Clone()
      {
        mzPath m_mzPathClone = (mzPath) this.internalmzPath.clone();
        return new GeoLine(this.coordSystem, m_mzPathClone);
      }

    @Override
    public byte[] getBlob()
      {
        return GeoConverter.Geom2Blob(this.internalmzPath);
      }

    @Override
    public Object getInternalObject()
      {
        return internalmzPath;
      }

    @Override
    public boolean isSimple()
      {
        return internalmzPath.IsSimple();
      }

    //获取长度
    public double getLength()
      {
        return internalmzPath.getLength();
      }

    //获取几何的真实长度，跨带线先分割，再投影到各自SRID下，再求长度和
    public double getLengthEx(ZoneType zoneType)
      {
        return internalmzPath.getLengthEx(zoneType.getValue());
      }

    public GeoPoint getPoint(int nIndex)
      {
        mzPoint m_mzPoint = internalmzPath.GetPoint(nIndex);
        return  new GeoPoint(this.coordSystem,m_mzPoint);
      }

  }
